package com.hskn.hss.module.oilDevice.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.hskn.hss.core.annotation.DataScope;
import com.hskn.hss.core.page.TableDataInfo;
import com.hskn.hss.module.carTrack.mapper.CarTrackMapper;
import com.hskn.hss.module.carviolation.entity.CarViolation;
import com.hskn.hss.module.carviolation.mapper.CarViolationMapper;
import com.hskn.hss.module.depart.service.ISysDepartService;
import com.hskn.hss.module.oilDevice.domain.StateOilDevice;
import com.hskn.hss.module.oilDevice.ex.to.OilConsumeExcelTO;
import com.hskn.hss.module.oilDevice.mapper.StateOilDeviceMapper;
import com.hskn.hss.module.oilDevice.service.IStateOilDeviceService;
import com.hskn.hss.module.oilDevice.to.AddOilSummaryTableTO;
import com.hskn.hss.module.oilDevice.to.MileageReportTableTO;
import com.hskn.hss.module.oilDevice.to.OilConsumeTO;
import com.hskn.hss.module.oilDevice.to.OilConsumeTableTO;
import com.hskn.hss.module.oilDevice.vo.MileageTableVO;
import com.hskn.hss.module.oilDevice.vo.OilConsumeVO;
import com.hskn.hss.module.oilDevice.vo.RefuelingSummaryECharsVO;
import com.hskn.hss.module.oilDevice.vo.StayReportTableVO;
import com.hskn.hss.module.tlopetation.entity.TlOperation;
import com.hskn.hss.module.tlopetation.service.ITlOperationService;
import com.hskn.hss.utils.*;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * 每日油量变化统计Service业务层处理
 *
 * @author ruoyi
 * @date 2021-08-05
 */
@Service
public class StateOilDeviceServiceImpl extends ServiceImpl<StateOilDeviceMapper, StateOilDevice> implements IStateOilDeviceService {
    @Autowired
    LocationUtils locationUtil;
    @Resource
    private StateOilDeviceMapper stateOilDeviceMapper;
    @Resource
    private ITlOperationService operationService;
    @Resource
    private CarViolationMapper carViolationMapper;
    @Resource
    private CarTrackMapper carTrackMapper;
    @Resource
    private ISysDepartService departService;

    /**
     * 查询每日油量变化统计
     *
     * @param id 每日油量变化统计主键
     * @return 每日油量变化统计
     */
    @Override
    public StateOilDevice selectStateOilDeviceById(String id) {
        return stateOilDeviceMapper.selectStateOilDeviceById(id);
    }

    /**
     * 查询每日油量变化统计列表
     *
     * @param stateOilDevice 每日油量变化统计
     * @return 每日油量变化统计
     */
    @Override
    public List<StateOilDevice> selectStateOilDeviceList(StateOilDevice stateOilDevice) {
        return stateOilDeviceMapper.selectStateOilDeviceList(stateOilDevice);
    }

    /**
     * 耗油
     *
     * @param oilConsumeTO
     * @return
     * @throws ParseException
     */
    @Override
    @DataScope(deptAlias = "deptidforcar_id")
    public List<List<Object>> selectStateOilDeviceForBTable(OilConsumeTO oilConsumeTO) throws ParseException {
        Date startDate = oilConsumeTO.getStartTime();
        Date endDate = oilConsumeTO.getEndTime();
        Integer dateType = oilConsumeTO.getDateType();
        if (oilConsumeTO.getDepId() != null && oilConsumeTO.getDepId() != "") {
            List<String> depIds = departService.getChildIdsByIId(oilConsumeTO.getDepId());
            oilConsumeTO.setDepIds(depIds);
        }
        List<BTable> list = stateOilDeviceMapper.selectStateOilDeviceForBTable(oilConsumeTO);
        if (dateType.equals(2)) {
            return Tools.getMonthEcharts(list, startDate, endDate);
        }
        return Tools.getDateEcharts(list, startDate, endDate);
    }


    /**
     * 耗油列表 也用于漏油 百公里耗油 设备加油列表
     *
     * @param oilConsumeTableTO
     * @return
     */
    @Override
    @DataScope(deptAlias = "deptidforcar_id")
    public List<OilConsumeVO> selectStateOilDeviceForTTable(OilConsumeTableTO oilConsumeTableTO) throws ParseException {
        List<OilConsumeVO> thisMonthList = stateOilDeviceMapper.selectStateOilDeviceForTTable(oilConsumeTableTO);
        QueryWrapper<StateOilDevice> stateOilDeviceQueryWrapper = new QueryWrapper<>();
        stateOilDeviceQueryWrapper.lambda().between(StateOilDevice::getDeviceDate,oilConsumeTableTO.getStartTime(),oilConsumeTableTO.getEndTime()).ge(StateOilDevice::getClockMileage,0.5);
        if(oilConsumeTableTO.getParams().containsKey("dataScope")&&StringUtils.isNotEmpty(oilConsumeTableTO.getParams().get("dataScope"))){
            stateOilDeviceQueryWrapper.lambda().apply(oilConsumeTableTO.getParams().get("dataScope").toString());
        }
        List<StateOilDevice> stateOilDeviceList = stateOilDeviceMapper.selectList(stateOilDeviceQueryWrapper);
        oilTableHandle(thisMonthList,oilConsumeTableTO.getStartTime(),oilConsumeTableTO.getEndTime(),stateOilDeviceList);
        for (OilConsumeVO oilConsumeVO : thisMonthList) {
            if (oilConsumeVO.getUseOilNum().compareTo(BigDecimal.ZERO) < 0) {
                oilConsumeVO.setUseOilNum(BigDecimal.ZERO);
            }
        }
        return thisMonthList;
    }

    /**
     * 各机构加油报表列表
     *
     * @param addOilSummaryTableTO
     * @return
     */
    @Override
    @DataScope(deptAlias = "deptidforcar_id")
    public List<OilConsumeVO> selectStateOilDeviceTableByDepId(AddOilSummaryTableTO addOilSummaryTableTO) throws ParseException {
        Date startTime = addOilSummaryTableTO.getStartTime();
        Date endTime = addOilSummaryTableTO.getEndTime();
        if (Objects.isNull(startTime)) {
            Calendar calendar = Calendar.getInstance();//获取当前日期
            if (calendar.get(Calendar.DAY_OF_MONTH) != 1) {
                startTime = Tools.getFristDayForDate(new Date());
            } else {
                calendar.add(Calendar.DAY_OF_MONTH, -1);
                startTime = Tools.getFristDayForDate(calendar.getTime());
            }
            addOilSummaryTableTO.setStartTime(startTime);
        }
        if (Objects.isNull(endTime)) {
            Calendar calendar = Calendar.getInstance();//获取当前日期
            if (calendar.get(Calendar.DAY_OF_MONTH) != 1) {
                endTime = Tools.getLastDayForDate(new Date());
            } else {
                calendar.add(Calendar.DAY_OF_MONTH, -1);
                endTime = Tools.getLastDayForDate(calendar.getTime());
            }
            addOilSummaryTableTO.setEndTime(endTime);
        }
        List<OilConsumeVO> thisMonthList = stateOilDeviceMapper.selectStateOilDeviceTableByDepId(addOilSummaryTableTO);
        Calendar calendarStart = new GregorianCalendar();
        calendarStart.setTime(startTime);
        calendarStart.add(Calendar.MONTH, -1);
        Date lastStartDate = Tools.getFristDayForDate(calendarStart.getTime());
        Calendar calendarEnd = new GregorianCalendar();
        calendarEnd.setTime(endTime);
        calendarEnd.add(Calendar.MONTH, -1);
        Date lastEndDate = Tools.getLastDayForDate(calendarEnd.getTime());
        addOilSummaryTableTO.setStartTime(lastStartDate);
        addOilSummaryTableTO.setEndTime(lastEndDate);
        List<OilConsumeVO> lastMonthList = stateOilDeviceMapper.selectStateOilDeviceTableByDepId(addOilSummaryTableTO);
        QueryWrapper<StateOilDevice> stateOilDeviceQueryWrapper = new QueryWrapper<>();
        stateOilDeviceQueryWrapper.lambda().between(StateOilDevice::getDeviceDate,startTime,endTime).ge(StateOilDevice::getClockMileage,0.5);
        if(addOilSummaryTableTO.getParams().containsKey("dataScope")&&StringUtils.isNotEmpty(addOilSummaryTableTO.getParams().get("dataScope"))){
            stateOilDeviceQueryWrapper.lambda().apply(addOilSummaryTableTO.getParams().get("dataScope").toString());
        }
        List<StateOilDevice> stateOilDeviceList = stateOilDeviceMapper.selectList(stateOilDeviceQueryWrapper);
        oilTableHandle(thisMonthList,addOilSummaryTableTO.getStartTime(),addOilSummaryTableTO.getEndTime(),stateOilDeviceList);
        Map<String, OilConsumeVO> lastMonthMap = GroupingByUtils.getGroupingForMapEntity(lastMonthList, OilConsumeVO::getDeptidforcarName, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        thisMonthList.forEach(x -> {
            if (lastMonthMap.containsKey(x.getDeptidforcarName())) {
                x.setAddOilMonthGrowth(x.getAddOilNum().subtract(lastMonthMap.get(x.getDeptidforcarName()).getAddOilNum()));
            } else {
                x.setAddOilMonthGrowth(x.getAddOilNum());
            }
        });
        return thisMonthList;
    }

    /**
     * 各作业类型报表列表
     *
     * @param addOilSummaryTableTO
     * @return
     */
    @Override
    @DataScope(deptAlias = "deptidforcar_id")
    public List<OilConsumeVO> selectStateOilDeviceTableByOperType(AddOilSummaryTableTO addOilSummaryTableTO) throws ParseException {
        Date startTime = addOilSummaryTableTO.getStartTime();
        Date endTime = addOilSummaryTableTO.getEndTime();
        if (Objects.isNull(startTime)) {
            Calendar calendar = Calendar.getInstance();//获取当前日期
            if (calendar.get(Calendar.DAY_OF_MONTH) != 1) {
                startTime = Tools.getFristDayForDate(new Date());
            } else {
                calendar.add(Calendar.DAY_OF_MONTH, -1);
                startTime = Tools.getFristDayForDate(calendar.getTime());
            }
            addOilSummaryTableTO.setStartTime(startTime);
        }
        if (Objects.isNull(endTime)) {
            Calendar calendar = Calendar.getInstance();//获取当前日期
            if (calendar.get(Calendar.DAY_OF_MONTH) != 1) {
                endTime = Tools.getLastDayForDate(new Date());
            } else {
                calendar.add(Calendar.DAY_OF_MONTH, -1);
                endTime = Tools.getLastDayForDate(calendar.getTime());
            }
            addOilSummaryTableTO.setEndTime(endTime);
        }
        List<OilConsumeVO> thisMonthList = stateOilDeviceMapper.selectStateOilDeviceTableByOperType(addOilSummaryTableTO);
        Calendar calendarStart = new GregorianCalendar();
        calendarStart.setTime(startTime);
        calendarStart.add(Calendar.MONTH, -1);
        Date lastStartDate = Tools.getFristDayForDate(calendarStart.getTime());
        Calendar calendarEnd = new GregorianCalendar();
        calendarEnd.setTime(endTime);
        calendarEnd.add(Calendar.MONTH, -1);
        Date lastEndDate = Tools.getLastDayForDate(calendarEnd.getTime());
        addOilSummaryTableTO.setStartTime(lastStartDate);
        addOilSummaryTableTO.setEndTime(lastEndDate);
        List<OilConsumeVO> lastMonthList = stateOilDeviceMapper.selectStateOilDeviceTableByOperType(addOilSummaryTableTO);
        Map<String, OilConsumeVO> lastMonthMap = GroupingByUtils.getGroupingForMapEntity(lastMonthList, OilConsumeVO::getCarcategoryName, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        thisMonthList.forEach(x -> {
            if (lastMonthMap.containsKey(x.getCarcategoryName())) {
                x.setAddOilMonthGrowth(x.getAddOilNum().subtract(lastMonthMap.get(x.getCarcategoryName()).getAddOilNum()));
            } else {
                x.setAddOilMonthGrowth(x.getAddOilNum());
            }
        });
        QueryWrapper<StateOilDevice> stateOilDeviceQueryWrapper = new QueryWrapper<>();
        stateOilDeviceQueryWrapper.lambda().between(StateOilDevice::getDeviceDate,startTime,endTime).ge(StateOilDevice::getClockMileage,0.5);
        if(addOilSummaryTableTO.getParams().containsKey("dataScope")&&StringUtils.isNotEmpty(addOilSummaryTableTO.getParams().get("dataScope"))){
            stateOilDeviceQueryWrapper.lambda().apply(addOilSummaryTableTO.getParams().get("dataScope").toString());
        }
        List<StateOilDevice> stateOilDeviceList = stateOilDeviceMapper.selectList(stateOilDeviceQueryWrapper);
        oilTableHandle(thisMonthList,addOilSummaryTableTO.getStartTime(),addOilSummaryTableTO.getEndTime(),stateOilDeviceList);
        thisMonthList = thisMonthList.stream().sorted(Comparator.comparing(OilConsumeVO::getCarcategoryName).thenComparing(OilConsumeVO::getDeviceDate)).collect(Collectors.toList());
        return thisMonthList;
    }

    /**
     * 各车辆类型报表列表
     *
     * @param addOilSummaryTableTO
     * @return
     */
    @Override
    @DataScope(deptAlias = "deptidforcar_id")
    public List<OilConsumeVO> selectStateOilDeviceTableByCarType(AddOilSummaryTableTO addOilSummaryTableTO) throws ParseException {
        Date startTime = addOilSummaryTableTO.getStartTime();
        Date endTime = addOilSummaryTableTO.getEndTime();
        if (Objects.isNull(startTime)) {
            Calendar calendar = Calendar.getInstance();//获取当前日期
            if (calendar.get(Calendar.DAY_OF_MONTH) != 1) {
                startTime = Tools.getFristDayForDate(new Date());
            } else {
                calendar.add(Calendar.DAY_OF_MONTH, -1);
                startTime = Tools.getFristDayForDate(calendar.getTime());
            }
            addOilSummaryTableTO.setStartTime(startTime);
        }
        if (Objects.isNull(endTime)) {
            Calendar calendar = Calendar.getInstance();//获取当前日期
            if (calendar.get(Calendar.DAY_OF_MONTH) != 1) {
                endTime = Tools.getLastDayForDate(new Date());
            } else {
                calendar.add(Calendar.DAY_OF_MONTH, -1);
                endTime = Tools.getLastDayForDate(calendar.getTime());
            }
            addOilSummaryTableTO.setEndTime(endTime);
        }
        List<OilConsumeVO> thisMonthList = stateOilDeviceMapper.selectStateOilDeviceTableByCarType(addOilSummaryTableTO);
        QueryWrapper<StateOilDevice> stateOilDeviceQueryWrapper = new QueryWrapper<>();
        stateOilDeviceQueryWrapper.lambda().between(StateOilDevice::getDeviceDate,startTime,endTime).ge(StateOilDevice::getClockMileage,0.5);
        if(addOilSummaryTableTO.getParams().containsKey("dataScope")&&StringUtils.isNotEmpty(addOilSummaryTableTO.getParams().get("dataScope"))){
            stateOilDeviceQueryWrapper.lambda().apply(addOilSummaryTableTO.getParams().get("dataScope").toString());
        }
        List<StateOilDevice> stateOilDeviceList = stateOilDeviceMapper.selectList(stateOilDeviceQueryWrapper);
        oilTableHandle(thisMonthList,addOilSummaryTableTO.getStartTime(),addOilSummaryTableTO.getEndTime(),stateOilDeviceList);
        Calendar calendarStart = new GregorianCalendar();
        calendarStart.setTime(startTime);
        calendarStart.add(Calendar.MONTH, -1);
        Date lastStartDate = Tools.getFristDayForDate(calendarStart.getTime());
        Calendar calendarEnd = new GregorianCalendar();
        calendarEnd.setTime(endTime);
        calendarEnd.add(Calendar.MONTH, -1);
        Date lastEndDate = Tools.getLastDayForDate(calendarEnd.getTime());
        addOilSummaryTableTO.setStartTime(lastStartDate);
        addOilSummaryTableTO.setEndTime(lastEndDate);
        List<OilConsumeVO> lastMonthList = stateOilDeviceMapper.selectStateOilDeviceTableByCarType(addOilSummaryTableTO);
        Map<String, OilConsumeVO> lastMonthMap = GroupingByUtils.getGroupingForMapEntity(lastMonthList, OilConsumeVO::getCarTypeName, Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)));
        thisMonthList.forEach(x -> {
            if (lastMonthMap.containsKey(x.getCarTypeName())) {
                x.setAddOilMonthGrowth(x.getAddOilNum().subtract(lastMonthMap.get(x.getCarTypeName()).getAddOilNum()));
            } else {
                x.setAddOilMonthGrowth(x.getAddOilNum());
            }
        });
        return thisMonthList;
    }

    /**
     * 漏油
     *
     * @param oilConsumeTO
     * @return
     * @throws ParseException
     */
    @Override
    @DataScope(deptAlias = "deptidforcar_id")
    public List<List<Object>> selectStateOilDeviceOfOutForBTable(OilConsumeTO oilConsumeTO) throws ParseException {
        Date startDate = oilConsumeTO.getStartTime();
        Date endDate = oilConsumeTO.getEndTime();
        Integer dateType = oilConsumeTO.getDateType();
        if (oilConsumeTO.getDepId() != null && oilConsumeTO.getDepId() != "") {
            List<String> depIds = departService.getChildIdsByIId(oilConsumeTO.getDepId());
            oilConsumeTO.setDepIds(depIds);
        }
        List<BTable> list = stateOilDeviceMapper.selectStateOilDeviceOfOutForBTable(oilConsumeTO);
        if (dateType.equals(2)) {
            return Tools.getMonthEcharts(list, startDate, endDate);
        }
        return Tools.getDateEcharts(list, startDate, endDate);
    }

    /**
     * 加油
     *
     * @param oilConsumeTO
     * @return
     * @throws ParseException
     */
    @Override
    @DataScope(deptAlias = "deptidforcar_id")
    public List<List<Object>> selectStateOilDeviceOfAddForBTable(OilConsumeTO oilConsumeTO) throws ParseException {
        Date startDate = oilConsumeTO.getStartTime();
        Date endDate = oilConsumeTO.getEndTime();
        Integer dateType = oilConsumeTO.getDateType();
        if (oilConsumeTO.getDepId() != null && oilConsumeTO.getDepId() != "") {
            List<String> depIds = departService.getChildIdsByIId(oilConsumeTO.getDepId());
            oilConsumeTO.setDepIds(depIds);
        }
        List<BTable> list = stateOilDeviceMapper.selectStateOilDeviceOfAddForBTable(oilConsumeTO);
        if (dateType.equals(2)) {
            return Tools.getMonthEcharts(list, startDate, endDate);
        }
        return Tools.getDateEcharts(list, startDate, endDate);
    }

    /**
     * 燃油报表列表统一处理
     *
     * @param thisMonthList
     * @throws ParseException
     */
    private void oilTableHandle(List<OilConsumeVO> thisMonthList, Date startDate, Date endDate,List<StateOilDevice> stateOilDeviceList) throws ParseException {
//        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat dtf = new SimpleDateFormat("YYYY年MM月");
//        List<String> dateList = new ArrayList<>();
//        dateList = Tools.getDateList(simpleDateFormat, startDate, endDate);

        Map<String, TlOperation> operationMap = operationService.getTlOperationMap(new QueryWrapper<>());
        for (OilConsumeVO oilConsumeVO : thisMonthList) {
            if (oilConsumeVO.getUseOilNum() != null) {
                Long ranDaysNum =stateOilDeviceList.stream().filter(x->x.getClockMileage().compareTo(new BigDecimal(0.5))>0&&x.getCarId().equals(oilConsumeVO.getCarId())).count();
                if (ranDaysNum > 0) {
                    oilConsumeVO.setUseOilEve(oilConsumeVO.getUseOilNum().divide(new BigDecimal(ranDaysNum), 2, BigDecimal.ROUND_HALF_UP));
                } else {
                    oilConsumeVO.setUseOilEve(new BigDecimal(-8888));
                }
                if (oilConsumeVO.getClockMileage() != null && oilConsumeVO.getClockMileage().compareTo(new BigDecimal(0.5)) > 0) {
                    oilConsumeVO.setBaiKmOil(oilConsumeVO.getUseOilNum().divide(oilConsumeVO.getClockMileage()
                            .divide(new BigDecimal(100), 6, BigDecimal.ROUND_HALF_UP), 2, BigDecimal.ROUND_HALF_UP));
                } else {
                    oilConsumeVO.setBaiKmOil(new BigDecimal(-8888));
                }
            }
            if (oilConsumeVO.getClockMileage() != null) {
                oilConsumeVO.setClockMileage(oilConsumeVO.getClockMileage().divide(new BigDecimal(1), 2, BigDecimal.ROUND_HALF_UP));
            }
            if (oilConsumeVO.getDeviceDate() != null) {
                oilConsumeVO.setMonTime(dtf.format(oilConsumeVO.getDeviceDate()));
            }
            if (operationMap.containsKey(oilConsumeVO.getCarcategoryName())) {
                oilConsumeVO.setCarcategoryName(operationMap.get(oilConsumeVO.getCarcategoryName()).getOperationtype());
            } else {
                oilConsumeVO.setCarcategoryName("-");
            }
        }
    }

    /**
     * 行驶EChars图
     *
     * @param mileageReportCharsTO
     * @return java.util.List<java.util.List < java.lang.Object>>
     * @author zcy
     * @date 2021/10/12 22:36
     */
    @Override
    public List<List<Object>> selectMileageReportChars(MileageReportTableTO mileageReportCharsTO) {
        QueryWrapper<StateOilDevice> oilDeviceQueryWrapper = getStateOilDeviceList(mileageReportCharsTO);
        List<StateOilDevice> oilDeviceList = stateOilDeviceMapper.selectList(oilDeviceQueryWrapper);
        oilDeviceList = oilDeviceList.stream().filter(x -> x.getMaxSpeed().compareTo(BigDecimal.ZERO) > 0 &&
                x.getMoveSecondSum().compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toList());
        Map<String, List<StateOilDevice>> odMap = GroupingByUtils.getGroupingForMapList(oilDeviceList, StateOilDevice::getCarTypeName);

        List<List<Object>> resList = new ArrayList<>();
        odMap.keySet().forEach(t -> {
            List<StateOilDevice> stateOilDevices = odMap.get(t);
            List<Object> list = new ArrayList<>();
            list.add(t);
            BigDecimal clockMileage = BigDecimal.ZERO;
            for (StateOilDevice stateOilDevice : stateOilDevices
            ) {
                clockMileage = clockMileage.add(stateOilDevice.getClockMileage());
            }
            list.add(clockMileage.divide(new BigDecimal("1"), 3, BigDecimal.ROUND_HALF_UP));
            resList.add(list);
        });
        return resList;
    }


    /**
     * 里程报表 行驶里程报表底部列表
     *
     * @param mileageReportCharsTO
     * @return java.util.List<com.hskn.hss.module.oilDevice.vo.MileageTableVO>
     * @author zcy
     * @date 2021/10/13 1:12
     */
    @Override
    public TableDataInfo selectMileageReportTable(MileageReportTableTO mileageReportCharsTO) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        QueryWrapper<StateOilDevice> oilDeviceQueryWrapper = getStateOilDeviceList(mileageReportCharsTO);
        List<StateOilDevice> oilDeviceList = stateOilDeviceMapper.selectList(oilDeviceQueryWrapper);
        Map<String, List<StateOilDevice>> stateOilDeviceMap = null;
        if (mileageReportCharsTO.getIsEve().equals(0)) {
            stateOilDeviceMap = oilDeviceList.stream().sorted(Comparator.comparing(StateOilDevice::getDeviceDate)).collect(Collectors.groupingBy(StateOilDevice::getCarnumber));
        } else {
            stateOilDeviceMap = oilDeviceList.stream().sorted(Comparator.comparing(StateOilDevice::getDeviceDate))
                    .collect(Collectors.groupingBy(stateOilDevice -> stateOilDevice.getCarnumber() + "_" + stateOilDevice.getDeviceDate()));
        }
        List<MileageTableVO> mileageTableVOList = new ArrayList<>();
        Map<String, List<StateOilDevice>> finalStateOilDeviceMap = stateOilDeviceMap;
        List<MileageTableVO> finalMileageTableVOList = mileageTableVOList;
        stateOilDeviceMap.keySet().forEach(t -> {
            List<StateOilDevice> stateOilDevices = finalStateOilDeviceMap.get(t);
            List<StateOilDevice> isNotNullStateOilDevices = stateOilDevices.stream().filter(
                    stateOilDevice -> Objects.nonNull(stateOilDevice.getStartDate()) && Objects.nonNull(stateOilDevice.getEndDate()) &&
                            StringUtils.isNotEmpty(stateOilDevice.getStartPosition()) && StringUtils.isNotEmpty(stateOilDevice.getEndPosition())
            ).collect(Collectors.toList());

            stateOilDevices.sort(Comparator.comparing(StateOilDevice::getDeviceDate));

            MileageTableVO mileageTableVO = new MileageTableVO();
            mileageTableVO.setCarnumber(stateOilDevices.get(0).getCarnumber());
            mileageTableVO.setCarId(stateOilDevices.get(0).getCarId());
            mileageTableVO.setCarTypeName(stateOilDevices.get(0).getCarTypeName());
            mileageTableVO.setDeptidforcarName(stateOilDevices.get(0).getDeptidforcarName());
            Integer runCount = 0;
            BigDecimal clockMileage = BigDecimal.ZERO;
            BigDecimal runTimeLength = BigDecimal.ZERO;
            BigDecimal maxSpeed = BigDecimal.ZERO;
            for (StateOilDevice stateOilDevice : stateOilDevices
            ) {
                runCount += stateOilDevice.getRunCount();
                clockMileage = clockMileage.add(stateOilDevice.getClockMileage());
                runTimeLength = runTimeLength.add(stateOilDevice.getMoveSecondSum());
                if (stateOilDevice.getMaxSpeed().compareTo(maxSpeed) > 0) {
                    maxSpeed = stateOilDevice.getMaxSpeed();
                }
                mileageTableVO.setDateString(simpleDateFormat.format(stateOilDevice.getDeviceDate()));
            }
            mileageTableVO.setRunCount(runCount);
            mileageTableVO.setClockMileage(clockMileage.divide(new BigDecimal("1"), 2, BigDecimal.ROUND_HALF_UP));
            mileageTableVO.setRunTimeLength(Tools.secondToTime(runTimeLength.divide(new BigDecimal("1000"), 2, BigDecimal.ROUND_HALF_UP).longValue()));
            mileageTableVO.setMaxSpend(maxSpeed);

//            QueryWrapper<CarTrack> carTrackQueryWrapper = new QueryWrapper<CarTrack>();
//            carTrackQueryWrapper.lambda().eq(CarTrack::getCarId, stateOilDevices.get(0).getCarId());
//            carTrackQueryWrapper.lambda().gt(CarTrack::getSpeed, 0);
//            carTrackQueryWrapper.lambda().orderByAsc(CarTrack::getTimestamp);
//            carTrackQueryWrapper.lambda().between(CarTrack::getTimestamp, mileageReportCharsTO.getStartTime(), mileageReportCharsTO.getEndTime());
//            carTrackQueryWrapper.lambda().last(" LIMIT 1");
//            CarTrack carTrack = carTrackMapper.selectOne(carTrackQueryWrapper);
//
//            if (Objects.nonNull(carTrack) && Objects.nonNull(carTrack.getTimestamp())){
//                mileageTableVO.setStartDate(carTrack.getTimestamp());
//            } else {
//                mileageTableVO.setStartDate(mileageReportCharsTO.getStartTime());
//            }
//
//            QueryWrapper<CarTrack> carTrackQueryWrapper2 = new QueryWrapper<CarTrack>();
//            carTrackQueryWrapper2.lambda().eq(CarTrack::getCarId, stateOilDevices.get(0).getCarId());
//            carTrackQueryWrapper2.lambda().gt(CarTrack::getSpeed, 0);
//            carTrackQueryWrapper2.lambda().orderByDesc(CarTrack::getTimestamp);
//            carTrackQueryWrapper2.lambda().between(CarTrack::getTimestamp, mileageReportCharsTO.getStartTime(), mileageReportCharsTO.getEndTime());
//            carTrackQueryWrapper2.lambda().last(" LIMIT 1");
//            CarTrack carTrack2 = carTrackMapper.selectOne(carTrackQueryWrapper2);
//
//            if (Objects.nonNull(carTrack2) && Objects.nonNull(carTrack2.getTimestamp())){
//                mileageTableVO.setEndDate(carTrack2.getTimestamp());
//            } else {
//                mileageTableVO.setEndDate(mileageReportCharsTO.getEndTime());
//            }
            if (!isNotNullStateOilDevices.isEmpty()) {
                mileageTableVO.setStartDate(isNotNullStateOilDevices.get(0).getStartDate());
                mileageTableVO.setEndDate(isNotNullStateOilDevices.get(isNotNullStateOilDevices.size() - 1).getEndDate());

                mileageTableVO.setStartPosition(isNotNullStateOilDevices.get(0).getStartPosition());
                mileageTableVO.setEndPosition(isNotNullStateOilDevices.get(isNotNullStateOilDevices.size() - 1).getEndPosition());
            }
            finalMileageTableVOList.add(mileageTableVO);
        });
        mileageTableVOList = mileageTableVOList.stream().filter(x -> x.getMaxSpend().compareTo(BigDecimal.ZERO) > 0 &&
                !x.getRunTimeLength().equals("0秒")).sorted(Comparator.comparing(MileageTableVO::getDateString).reversed()).collect(Collectors.toList());
        return Tools.buildTableDataInfo(mileageReportCharsTO.getPage(), mileageReportCharsTO.getSize(), mileageTableVOList);
    }

    private QueryWrapper<StateOilDevice> getStateOilDeviceList(MileageReportTableTO mileageReportCharsTO) {
        if (Objects.isNull(mileageReportCharsTO.getStartTime())) {
            mileageReportCharsTO.setStartTime(DateUtil.parseDateTime(DateUtil.format(new Date(), DatePattern.NORM_MONTH_PATTERN) + "-01 00:00:00"));
        } else {
            mileageReportCharsTO.setStartTime(DateUtil.parseDateTime(DateUtil.formatDate(mileageReportCharsTO.getStartTime()) + " 00:00:00"));
        }
        if (Objects.isNull(mileageReportCharsTO.getEndTime())) {
            mileageReportCharsTO.setEndTime(DateUtil.parseDateTime(DateUtil.formatDate(new Date()) + " 23:59:59"));
        } else {
            mileageReportCharsTO.setEndTime(DateUtil.parseDateTime(DateUtil.formatDate(mileageReportCharsTO.getEndTime()) + " 23:59:59"));
        }
        String carId = mileageReportCharsTO.getCarId();
        String depId = mileageReportCharsTO.getDepId();
        String carTypeId = mileageReportCharsTO.getCarTypeId();
        Date startDate = mileageReportCharsTO.getStartTime();
        Date endDate = mileageReportCharsTO.getEndTime();
        List<String> carnumbers = mileageReportCharsTO.getCarnumbers();
        QueryWrapper<StateOilDevice> oilDeviceQueryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(carId)) {
            oilDeviceQueryWrapper.lambda().eq(StateOilDevice::getCarId, carId);
        }
        if (StringUtils.isNotEmpty(depId)) {
            List<String> depIds = departService.getChildIdsByIId(depId);
            oilDeviceQueryWrapper.lambda().in(StateOilDevice::getDeptidforcarId, depIds);
        }
        if (StringUtils.isNotEmpty(carTypeId)) {
            oilDeviceQueryWrapper.lambda().eq(StateOilDevice::getCarTypeId, carTypeId);
        }
        if (Objects.nonNull(startDate) && Objects.nonNull(endDate)) {
            oilDeviceQueryWrapper.lambda().between(StateOilDevice::getDeviceDate, startDate, endDate);
        }
        oilDeviceQueryWrapper.lambda().orderByAsc(StateOilDevice::getDeviceDate);
        if (Objects.nonNull(carnumbers)) {
            oilDeviceQueryWrapper.lambda().in(StateOilDevice::getCarnumber, carnumbers);
        }
        return oilDeviceQueryWrapper;
    }

    private MileageTableVO getMileageTableVO(List<StateOilDevice> childStateOilDeviceList) {
        String carNumber = "";
        String carTypeName = "";
        String deptidforcarName = "";
        Integer runCount = 0;
        BigDecimal clockMileage = BigDecimal.ZERO;
        BigDecimal runTimeLength = BigDecimal.ZERO;
        BigDecimal maxSpend = BigDecimal.ZERO;
        Date startDate = null;
        Date endDate = null;
        String startPosition = "";
        String endPosition = "";
        for (StateOilDevice stateOilDevice : childStateOilDeviceList) {
            if (StringUtils.isNotEmpty(stateOilDevice.getCarnumber()) && StringUtils.isEmpty(carNumber)) {
                carNumber = stateOilDevice.getCarnumber();
            }
            if (StringUtils.isNotEmpty(stateOilDevice.getCarTypeName()) && StringUtils.isEmpty(carTypeName)) {
                carTypeName = stateOilDevice.getCarTypeName();
            }
            if (StringUtils.isNotEmpty(stateOilDevice.getDeptidforcarName()) && StringUtils.isEmpty(deptidforcarName)) {
                deptidforcarName = stateOilDevice.getDeptidforcarName();
            }
            runCount += stateOilDevice.getRunCount();
            clockMileage = clockMileage.add(stateOilDevice.getClockMileage());
            runTimeLength = runTimeLength.add(stateOilDevice.getMoveSecondSum());
            if (Objects.nonNull(stateOilDevice.getMaxSpeed()) && maxSpend.compareTo(stateOilDevice.getMaxSpeed()) < 0) {
                maxSpend = stateOilDevice.getMaxSpeed();
            }
            if (Objects.isNull(startDate) && Objects.nonNull(stateOilDevice.getStartDate())) {
                startDate = stateOilDevice.getStartDate();
            }
            endDate = stateOilDevice.getEndDate();
            if (StringUtils.isNotEmpty(stateOilDevice.getStartPosition()) && StringUtils.isEmpty(startPosition)) {
                startPosition = stateOilDevice.getStartPosition();
            }
            endPosition = stateOilDevice.getEndPosition();
        }
        MileageTableVO mileageTableVO = new MileageTableVO();
        mileageTableVO.setCarnumber(carNumber);
        mileageTableVO.setCarTypeName(carTypeName);
        mileageTableVO.setDeptidforcarName(deptidforcarName);
        mileageTableVO.setRunCount(runCount);
        mileageTableVO.setClockMileage(clockMileage.divide(new BigDecimal(1), 2, BigDecimal.ROUND_HALF_UP));
        mileageTableVO.setRunTimeLength(Tools.secondToTime(runTimeLength.divide(new BigDecimal(1000), 2, BigDecimal.ROUND_HALF_UP).longValue()));
        mileageTableVO.setMaxSpend(maxSpend);
        mileageTableVO.setStartDate(startDate);
        mileageTableVO.setEndDate(endDate);
        mileageTableVO.setStartPosition(startPosition);
        mileageTableVO.setEndPosition(endPosition);

        return mileageTableVO;
    }

    /**
     * 加油汇总图
     *
     * @param
     * @return java.util.List<java.util.List < java.lang.Object>>
     * @author zcy
     * @date 2021/10/12 22:36
     */
    @Override
    @DataScope(deptAlias = "deptidforcar_id")
    public RefuelingSummaryECharsVO getRefuelingSummaryECharsVO(AddOilSummaryTableTO addOilSummaryTableTO) {
        String carTypeId = addOilSummaryTableTO.getCarTypeId();
        String deptidforcarId = addOilSummaryTableTO.getDeptidforcarId();
        String deptidforcarType = addOilSummaryTableTO.getDeptidforcarType();
        Date startTime = addOilSummaryTableTO.getStartTime();
        Date lastStartTime = new Date();
        Date lastEndTime = new Date();
        Date endTime = addOilSummaryTableTO.getEndTime();
        if (Objects.isNull(startTime)) {
            Calendar calendar = Calendar.getInstance();//获取当前日期
            if (calendar.get(Calendar.DAY_OF_MONTH) != 1) {
                startTime = Tools.getFristDayForDate(new Date());
            } else {
                calendar.add(Calendar.DAY_OF_MONTH, -1);
                startTime = Tools.getFristDayForDate(calendar.getTime());
            }
        }
        if (Objects.isNull(endTime)) {
            Calendar calendar = Calendar.getInstance();//获取当前日期
            if (calendar.get(Calendar.DAY_OF_MONTH) != 1) {
                endTime = Tools.getLastDayForDate(new Date());
            } else {
                calendar.add(Calendar.DAY_OF_MONTH, -1);
                endTime = Tools.getLastDayForDate(calendar.getTime());
            }
        }
        QueryWrapper<StateOilDevice> oilDeviceQueryWrapper = new QueryWrapper<>();
        if (addOilSummaryTableTO.getParams().containsKey("dataScope") && StringUtils.isNotEmpty(addOilSummaryTableTO.getParams().get("dataScope").toString())) {
            oilDeviceQueryWrapper.lambda().apply(addOilSummaryTableTO.getParams().get("dataScope").toString());
        }
        if (StringUtils.isNotEmpty(carTypeId)) {
            oilDeviceQueryWrapper.lambda().eq(StateOilDevice::getCarTypeId, carTypeId);
        }
        if (StringUtils.isNotEmpty(deptidforcarId)) {
            List<String> depIds = departService.getChildIdsByIId(deptidforcarId);
            oilDeviceQueryWrapper.lambda().in(StateOilDevice::getDeptidforcarId, depIds);
        }
        if (StringUtils.isNotEmpty(deptidforcarType)) {
            oilDeviceQueryWrapper.lambda().eq(StateOilDevice::getDeptidforcarType, deptidforcarType);
        }
        if (Objects.nonNull(startTime) && Objects.nonNull(endTime)) {
            Calendar calendar = new GregorianCalendar();
            calendar.setTime(startTime);
            calendar.add(Calendar.MONTH, -1);
            lastStartTime = calendar.getTime();
            lastEndTime = Tools.getLastDayForDate(calendar.getTime());
            oilDeviceQueryWrapper.lambda().between(StateOilDevice::getDeviceDate, Tools.getDateForBegin(lastStartTime), Tools.getDateForEnd(endTime));
        }
        List<StateOilDevice> twoMonthList = stateOilDeviceMapper.selectList(oilDeviceQueryWrapper);
        Date finalStartTime = startTime;
        Date finalEndTime = endTime;
        List<StateOilDevice> thisMonthList = twoMonthList.stream().filter(x -> x.getDeviceDate().getTime() >= finalStartTime.getTime() && x.getDeviceDate().getTime() <= finalEndTime.getTime()).collect(Collectors.toList());
        Date finalLastStartTime = lastStartTime;
        Date finalLastEndTime = lastEndTime;
        List<StateOilDevice> lastMonthList = twoMonthList.stream().filter(x -> x.getDeviceDate().getTime() >= finalLastStartTime.getTime() && x.getDeviceDate().getTime() <= finalLastEndTime.getTime()).collect(Collectors.toList());

        return buildRefuelingSummaryECharsVO(thisMonthList, lastMonthList);
    }

    private RefuelingSummaryECharsVO buildRefuelingSummaryECharsVO(List<StateOilDevice> thisMonthList, List<StateOilDevice> lastMonthList) {
        RefuelingSummaryECharsVO refuelingSummaryECharsVO = new RefuelingSummaryECharsVO();
        if (Objects.isNull(thisMonthList) &&
                thisMonthList.isEmpty()) {
            return refuelingSummaryECharsVO;
        }
        //作业类型
        Map<String, TlOperation> operationMap = operationService.getTlOperationMap(new QueryWrapper<>());
        Map<String, List<StateOilDevice>> workMap = GroupingByUtils.getGroupingForMapList(thisMonthList, StateOilDevice::getCarcategoryId);
        List<BTable> workBTableList = buildBTableForStateOilDevice(workMap);
        workBTableList.forEach(x -> x.setTime(operationMap.get(x.getTime()).getOperationtype()));
        refuelingSummaryECharsVO.setJobDistributionEChars(Tools.getBTable(workBTableList));
        //车辆类型
        Map<String, List<StateOilDevice>> typeMap = GroupingByUtils.getGroupingForMapList(thisMonthList, StateOilDevice::getCarTypeName);
        List<BTable> typeBTableList = buildBTableForStateOilDevice(typeMap);
        refuelingSummaryECharsVO.setVehicleTypeDistributionEChars(Tools.getBTable(typeBTableList));
        //其他处理
        BigDecimal thisMonthSum = BigDecimal.ZERO;
        BigDecimal lastMonthSum = BigDecimal.ZERO;
        for (StateOilDevice stateOilDevice : thisMonthList) {
            thisMonthSum = thisMonthSum.add(stateOilDevice.getAddOilNum());
        }
        for (StateOilDevice stateOilDevice : lastMonthList) {
            lastMonthSum = lastMonthSum.add(stateOilDevice.getAddOilNum());
        }

        refuelingSummaryECharsVO.setAddOilNum(thisMonthSum);
        refuelingSummaryECharsVO.setAddOilMonthGrowthNum(thisMonthSum.subtract(lastMonthSum));
        if (lastMonthSum.compareTo(BigDecimal.ZERO) > 0 && thisMonthSum.compareTo(BigDecimal.ZERO) >= 0) {
            refuelingSummaryECharsVO.setAddOilMonthGrowthPercentage(thisMonthSum.subtract(lastMonthSum).multiply(new BigDecimal(100))
                    .divide(lastMonthSum, 2, BigDecimal.ROUND_HALF_UP));
        } else if (lastMonthSum.compareTo(BigDecimal.ZERO) == 0 && thisMonthSum.compareTo(BigDecimal.ZERO) > 0) {
            refuelingSummaryECharsVO.setAddOilMonthGrowthPercentage(new BigDecimal(100));
        } else {
            refuelingSummaryECharsVO.setAddOilMonthGrowthPercentage(BigDecimal.ZERO);
        }
        return refuelingSummaryECharsVO;
    }

    private List<BTable> buildBTableForStateOilDevice(Map<String, List<StateOilDevice>> stateOilDeviceMap) {
        List<BTable> bTableList = new ArrayList<>();
        BigDecimal sum = BigDecimal.ZERO;
        for (String s : stateOilDeviceMap.keySet()) {
            sum = BigDecimal.ZERO;
            for (StateOilDevice stateOilDevice : stateOilDeviceMap.get(s)) {
                sum = sum.add(stateOilDevice.getAddOilNum());
            }
            bTableList.add(new BTable(s, sum));
        }
        return bTableList;
    }

    /**
     * 停留图
     *
     * @param carViolationList
     * @return java.util.List<java.util.List < java.lang.Object>>
     * @author zcy
     * @date 2021/10/14 15:39
     */
    @Override
    public List<List<Object>> stayReportEChars(List<CarViolation> carViolationList) {
        Map<String, List<CarViolation>> CVMap = GroupingByUtils.getGroupingForMapList(carViolationList, CarViolation::getCarTypeName);

        List<List<Object>> resList = new ArrayList<>();
        CVMap.keySet().forEach(t -> {
            List<CarViolation> carViolations = CVMap.get(t);
            List<Object> list = new ArrayList<>();
            list.add(t);
            BigDecimal stayTime = BigDecimal.ZERO;
            for (CarViolation carViolation : carViolations
            ) {
                stayTime = stayTime.add(carViolation.getViolationValue());
            }
            stayTime = stayTime.divide(new BigDecimal("3600"), 3, BigDecimal.ROUND_HALF_UP);
            list.add(stayTime);
            resList.add(list);
        });
        return resList;
    }

    /**
     * 停留列表
     *
     * @param mileageReportTableTO
     * @param carViolationList
     * @return java.util.List<com.hskn.hss.module.oilDevice.vo.StayReportTableVO>
     * @author zcy
     * @date 2021/10/14 15:40
     */
    @Override
    public TableDataInfo stayReportTable(MileageReportTableTO mileageReportTableTO,List<CarViolation> carViolationList) {
        Map<String, List<CarViolation>> carVioMap = GroupingByUtils.getGroupingForMapList(carViolationList, CarViolation::getCarId);
        List<StayReportTableVO> stayReportTableVOList = new ArrayList<>();
        carVioMap.keySet().forEach(t -> {
            List<CarViolation> carViolations = carVioMap.get(t);
            StayReportTableVO stayReportTableVO = new StayReportTableVO();
            stayReportTableVO.setCarId(carViolations.get(0).getCarId());
            stayReportTableVO.setCarnumber(carViolations.get(0).getCarName());
            stayReportTableVO.setCarTypeName(carViolations.get(0).getCarTypeName());
            stayReportTableVO.setDeptidforcarName(carViolations.get(0).getDepName());
            stayReportTableVO.setStayCount(carViolations.size());
            BigDecimal stayTime = BigDecimal.ZERO;
            for (CarViolation carViolation : carViolations
            ) {
                stayTime = stayTime.add(carViolation.getViolationValue());
            }

            stayReportTableVO.setStayTimeLength(Tools.secondToTime(stayTime.longValue()));
            stayReportTableVOList.add(stayReportTableVO);
        });
        return Tools.buildTableDataInfo(mileageReportTableTO.getPage(), mileageReportTableTO.getSize(), stayReportTableVOList);
    }

    /**
     * 停留列表明细
     *
     * @param mileageReportTableTO
     * @param carViolationList
     * @return java.util.List<com.hskn.hss.module.oilDevice.vo.StayReportTableVO>
     * @author zcy
     * @date 2021/10/14 15:40
     */
    @Override
    public TableDataInfo stayReportTableDetail(MileageReportTableTO mileageReportTableTO,List<CarViolation> carViolationList) {
        List<StayReportTableVO> stayReportTableVOList = new ArrayList<>();
        carViolationList.forEach(t -> {
            StayReportTableVO stayReportTableVO = new StayReportTableVO();
            stayReportTableVO.setCarnumber(t.getCarName());
            stayReportTableVO.setCarTypeName(t.getCarTypeName());
            stayReportTableVO.setDeptidforcarName(t.getDepName());
            stayReportTableVO.setStayStartTime(DateUtil.formatDateTime(t.getViolationStartTime()));
            stayReportTableVO.setStayEndTime(DateUtil.formatDateTime(t.getViolationEndTime()));
            stayReportTableVO.setStayTimeLength(StringUtils.s2date(t.getViolationValue().longValue()));
            /** 保存地址 **/
            String currentAddress = locationUtil.getAddress(t.getLng(), t.getLat());
            if (StringUtils.isNotEmpty(currentAddress)) {
                stayReportTableVO.setStayAddress(currentAddress);
            } else {
                stayReportTableVO.setStayAddress("");
            }
            stayReportTableVOList.add(stayReportTableVO);
        });
        return Tools.buildTableDataInfo(mileageReportTableTO.getPage(), mileageReportTableTO.getSize(), stayReportTableVOList);
    }

    //    private StayReportTableVO getStayReportTableVO(List<CarViolation> carViolationList,Map<String,
//            TlCarType> carTypeMap,Map<String,TlCar> carMap,Map<String, SysDepart> departMap){
//        String carName="";
//        String carTypeName="";
//        String depName="";
//        Integer stayCount=Objects.nonNull(carViolationList)?carViolationList.size():0;
//        BigDecimal stayTimeLength = BigDecimal.ZERO;
//        Date startDate=new Date();
//        Date endDate=new Date();
//        for(CarViolation carViolation:carViolationList){
//            startDate=carViolation.getViolationStartTime();
//            endDate=carViolation.getViolationEndTime();
//            if (StringUtils.isNotEmpty(carViolation.getCarTypeId())&&StringUtils.isEmpty(carTypeName)){
//                carTypeName=carTypeMap.get(carViolation.getCarTypeId()).getTypename();
//            }
//            if (StringUtils.isNotEmpty(carViolation.getCarId())&&StringUtils.isEmpty(carName)){
//                carName=carMap.get(carViolation.getCarId()).getCarnumber();
//            }
//            if (StringUtils.isNotEmpty(carViolation.getDepid())&&StringUtils.isEmpty(depName)){
//                depName=departMap.get(carViolation.getDepid()).getDepartName();
//            }
//            if (Objects.nonNull(startDate)&&Objects.nonNull(endDate)){
//                stayTimeLength=stayTimeLength.add(new BigDecimal(endDate.getTime()-startDate.getTime()));
//            }
//
//        }
//        return new StayReportTableVO(carName,carTypeName,depName,stayCount,StringUtils.s2date(stayTimeLength.longValue()));
//    }
    @DataScope(deptAlias = "deptidforcar_id")
    @Override
    public List<CarViolation> getCarViolationList(MileageReportTableTO mileageReportTableTO) {
        if (Objects.isNull(mileageReportTableTO.getStartTime())) {
            mileageReportTableTO.setStartTime(DateUtil.parseDateTime(DateUtil.format(new Date(), DatePattern.NORM_MONTH_PATTERN) + "-01 00:00:00"));
        } else {
            mileageReportTableTO.setStartTime(DateUtil.parseDateTime(DateUtil.formatDate(mileageReportTableTO.getStartTime()) + " 00:00:00"));
        }
        if (Objects.isNull(mileageReportTableTO.getEndTime())) {
            mileageReportTableTO.setEndTime(DateUtil.parseDateTime(DateUtil.formatDate(new Date()) + " 23:59:59"));
        } else {
            mileageReportTableTO.setEndTime(DateUtil.parseDateTime(DateUtil.formatDate(mileageReportTableTO.getEndTime()) + " 23:59:59"));
        }
        QueryWrapper<CarViolation> carQueryWrapper = new QueryWrapper<>();
        String carId = mileageReportTableTO.getCarId();
        String depId = mileageReportTableTO.getDepId();
        Date startDate = mileageReportTableTO.getStartTime();
        Date endDate = mileageReportTableTO.getEndTime();
        List<String> carIds = mileageReportTableTO.getCarIds();

        if (StringUtils.isNotEmpty(carId)) {
            carQueryWrapper.lambda().eq(CarViolation::getCarId, carId);
        }
        if (StringUtils.isNotEmpty(depId)) {
            List<String> depIds = departService.getChildIdsByIId(depId);
            carQueryWrapper.lambda().in(CarViolation::getDepid, depIds);
        }
        if (Objects.nonNull(startDate) && Objects.nonNull(endDate)) {
            carQueryWrapper.lambda().between(CarViolation::getTime, startDate, endDate);
        }
        if (Objects.nonNull(carIds)) {
            carQueryWrapper.lambda().in(CarViolation::getCarId, carIds);
        }
        if(mileageReportTableTO.getParams().containsKey("dataScope")&&StringUtils.isNotEmpty(mileageReportTableTO.getParams().get("dataScope"))){
            carQueryWrapper.lambda().apply(mileageReportTableTO.getParams().get("dataScope").toString());
        }
        carQueryWrapper.lambda().eq(CarViolation::getRuleTypeName, "车辆停留");
        List<CarViolation> carViolationList = carViolationMapper.selectList(carQueryWrapper);
        return carViolationList;
    }

    /**
     * 耗油报表 百公里耗油报表导出
     *
     * @param oilConsumeTableExcelTO
     * @return
     * @throws ParseException
     */
    @DataScope(deptAlias = "deptidforcar_id")
    @Override
    public List<OilConsumeVO> selectStateOilDeviceForExcel(OilConsumeExcelTO oilConsumeTableExcelTO) throws ParseException {
        Date startTime = oilConsumeTableExcelTO.getStartTime();
        Date endTime = oilConsumeTableExcelTO.getEndTime();
        List<OilConsumeVO> thisMonthList = stateOilDeviceMapper.selectStateOilDeviceForExcel(oilConsumeTableExcelTO);
        if (CollectionUtils.isNotEmpty(oilConsumeTableExcelTO.getTimes())) {
            Predicate<OilConsumeVO> inTime = x -> (oilConsumeTableExcelTO.getTimes().contains(Tools.getYearMonthDayString(x.getDeviceDate())));
            thisMonthList = thisMonthList.stream().filter(inTime).collect(Collectors.toList());
        }
        QueryWrapper<StateOilDevice> stateOilDeviceQueryWrapper = new QueryWrapper<>();
        stateOilDeviceQueryWrapper.lambda().between(StateOilDevice::getDeviceDate,startTime,endTime).ge(StateOilDevice::getClockMileage,0.5);
        if(oilConsumeTableExcelTO.getParams().containsKey("dataScope")&&StringUtils.isNotEmpty(oilConsumeTableExcelTO.getParams().get("dataScope"))){
            stateOilDeviceQueryWrapper.lambda().apply(oilConsumeTableExcelTO.getParams().get("dataScope").toString());
        }
        List<StateOilDevice> stateOilDeviceList = stateOilDeviceMapper.selectList(stateOilDeviceQueryWrapper);
        oilTableHandle(thisMonthList,startTime,endTime,stateOilDeviceList);
        for (OilConsumeVO oilConsumeVO : thisMonthList) {
            if (oilConsumeVO.getUseOilNum().compareTo(BigDecimal.ZERO) < 0) {
                oilConsumeVO.setUseOilNum(BigDecimal.ZERO);
            }
            if (oilConsumeVO.getBaiKmOil().compareTo(BigDecimal.ZERO) < 0) {
                oilConsumeVO.setBaiKmOil(BigDecimal.ZERO);
            }
        }
        return thisMonthList;
    }

    /**
     * 停留列表导出
     *
     * @param carViolationList
     * @return java.util.List<com.hskn.hss.module.oilDevice.vo.StayReportTableVO>
     * @author zcy
     * @date 2021/10/14 15:40
     */
    @Override
    public List<StayReportTableVO> stayReportTableExcel(List<CarViolation> carViolationList) {
        Map<String, List<CarViolation>> carVioMap = GroupingByUtils.getGroupingForMapList(carViolationList, CarViolation::getCarId);
        List<StayReportTableVO> stayReportTableVOList = new ArrayList<>();
        carVioMap.keySet().forEach(t -> {
            List<CarViolation> carViolations = carVioMap.get(t);
            StayReportTableVO stayReportTableVO = new StayReportTableVO();
            stayReportTableVO.setCarId(carViolations.get(0).getCarId());
            stayReportTableVO.setCarnumber(carViolations.get(0).getCarName());
            stayReportTableVO.setCarTypeName(carViolations.get(0).getCarTypeName());
            stayReportTableVO.setDeptidforcarName(carViolations.get(0).getDepName());
            stayReportTableVO.setStayCount(carViolations.size());
            BigDecimal stayTime = BigDecimal.ZERO;
            for (CarViolation carViolation : carViolations
            ) {
                stayTime = stayTime.add(carViolation.getViolationValue());
            }

            stayReportTableVO.setStayTimeLength(Tools.secondToTime(stayTime.longValue()));
            stayReportTableVOList.add(stayReportTableVO);
        });
        return stayReportTableVOList;
        //return Tools.buildTableDataInfo(mileageReportTableTO.getPage(), mileageReportTableTO.getSize(), stayReportTableVOList);
    }

    /**
     * 停留列表明细导出
     *
     * @param carViolationList
     * @return java.util.List<com.hskn.hss.module.oilDevice.vo.StayReportTableVO>
     * @author zcy
     * @date 2021/10/14 15:40
     */
    @Override
    public List<StayReportTableVO> stayReportTableDetailExcel(List<CarViolation> carViolationList) {
        List<StayReportTableVO> stayReportTableVOList = new ArrayList<>();
        carViolationList.forEach(t -> {
            StayReportTableVO stayReportTableVO = new StayReportTableVO();
            stayReportTableVO.setCarnumber(t.getCarName());
            stayReportTableVO.setCarTypeName(t.getCarTypeName());
            stayReportTableVO.setDeptidforcarName(t.getDepName());
            stayReportTableVO.setStayStartTime(DateUtil.formatDateTime(t.getViolationStartTime()));
            stayReportTableVO.setStayEndTime(DateUtil.formatDateTime(t.getViolationEndTime()));
            stayReportTableVO.setStayTimeLength(StringUtils.s2date(t.getViolationValue().longValue()));
            /** 保存地址 **/
            String currentAddress = locationUtil.getAddress(t.getLng(), t.getLat());
            if (StringUtils.isNotEmpty(currentAddress)) {
                stayReportTableVO.setStayAddress(currentAddress);
            } else {
                stayReportTableVO.setStayAddress("");
            }
            stayReportTableVOList.add(stayReportTableVO);
        });
        return stayReportTableVOList;
        //return Tools.buildTableDataInfo(mileageReportTableTO.getPage(), mileageReportTableTO.getSize(), stayReportTableVOList);
    }

    /**
     * 里程报表 行驶里程报表底部列表导出
     *
     * @param mileageReportCharsTO
     * @return java.util.List<com.hskn.hss.module.oilDevice.vo.MileageTableVO>
     * @author zcy
     * @date 2021/10/13 1:12
     */
    @DataScope(deptAlias = "deptidforcar_id")
    @Override
    public List<MileageTableVO> selectMileageReportTableExcel(MileageReportTableTO mileageReportCharsTO) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        QueryWrapper<StateOilDevice> oilDeviceQueryWrapper = getStateOilDeviceList(mileageReportCharsTO);
        List<StateOilDevice> oilDeviceList = stateOilDeviceMapper.selectList(oilDeviceQueryWrapper);
        if (CollectionUtils.isNotEmpty(mileageReportCharsTO.getTimes())) {
            Predicate<StateOilDevice> inTime = x -> (mileageReportCharsTO.getTimes().contains(Tools.getYearMonthDayString(x.getDeviceDate())));
            oilDeviceList = oilDeviceList.stream().filter(inTime).collect(Collectors.toList());
        }
        Map<String, List<StateOilDevice>> stateOilDeviceMap = null;
        if (mileageReportCharsTO.getIsEve().equals(0)) {
            stateOilDeviceMap = oilDeviceList.stream().sorted(Comparator.comparing(StateOilDevice::getDeviceDate)).collect(Collectors.groupingBy(StateOilDevice::getCarnumber));
        } else {
            stateOilDeviceMap = oilDeviceList.stream().sorted(Comparator.comparing(StateOilDevice::getDeviceDate))
                    .collect(Collectors.groupingBy(stateOilDevice -> stateOilDevice.getCarnumber() + "_" + stateOilDevice.getDeviceDate()));
        }
        List<MileageTableVO> mileageTableVOList = new ArrayList<>();
        Map<String, List<StateOilDevice>> finalStateOilDeviceMap = stateOilDeviceMap;
        List<MileageTableVO> finalMileageTableVOList = mileageTableVOList;
        stateOilDeviceMap.keySet().forEach(t -> {
            List<StateOilDevice> stateOilDevices = finalStateOilDeviceMap.get(t);
            List<StateOilDevice> isNotNullStateOilDevices = stateOilDevices.stream().filter(
                    stateOilDevice -> Objects.nonNull(stateOilDevice.getStartDate()) && Objects.nonNull(stateOilDevice.getEndDate()) &&
                            StringUtils.isNotEmpty(stateOilDevice.getStartPosition()) && StringUtils.isNotEmpty(stateOilDevice.getEndPosition())
            ).collect(Collectors.toList());

            stateOilDevices.sort(Comparator.comparing(StateOilDevice::getDeviceDate));

            MileageTableVO mileageTableVO = new MileageTableVO();
            mileageTableVO.setCarnumber(stateOilDevices.get(0).getCarnumber());
            mileageTableVO.setCarTypeName(stateOilDevices.get(0).getCarTypeName());
            mileageTableVO.setDeptidforcarName(stateOilDevices.get(0).getDeptidforcarName());
            Integer runCount = 0;
            BigDecimal clockMileage = BigDecimal.ZERO;
            BigDecimal runTimeLength = BigDecimal.ZERO;
            BigDecimal maxSpeed = BigDecimal.ZERO;
            for (StateOilDevice stateOilDevice : stateOilDevices
            ) {
                runCount += stateOilDevice.getRunCount();
                clockMileage = clockMileage.add(stateOilDevice.getClockMileage());
                runTimeLength = runTimeLength.add(stateOilDevice.getMoveSecondSum());
                if (stateOilDevice.getMaxSpeed().compareTo(maxSpeed) > 0) {
                    maxSpeed = stateOilDevice.getMaxSpeed();
                }
                mileageTableVO.setDateString(simpleDateFormat.format(stateOilDevice.getDeviceDate()));
            }
            mileageTableVO.setRunCount(runCount);
            mileageTableVO.setClockMileage(clockMileage.divide(new BigDecimal("1"), 2, BigDecimal.ROUND_HALF_UP));
            mileageTableVO.setRunTimeLength(Tools.secondToTime(runTimeLength.divide(new BigDecimal("1000"), 2, BigDecimal.ROUND_HALF_UP).longValue()));
            mileageTableVO.setMaxSpend(maxSpeed);

//            QueryWrapper<CarTrack> carTrackQueryWrapper = new QueryWrapper<CarTrack>();
//            carTrackQueryWrapper.lambda().eq(CarTrack::getCarId, stateOilDevices.get(0).getCarId());
//            carTrackQueryWrapper.lambda().gt(CarTrack::getSpeed, 0);
//            carTrackQueryWrapper.lambda().orderByAsc(CarTrack::getTimestamp);
//            carTrackQueryWrapper.lambda().between(CarTrack::getTimestamp, mileageReportCharsTO.getStartTime(), mileageReportCharsTO.getEndTime());
//            carTrackQueryWrapper.lambda().last(" LIMIT 1");
//            CarTrack carTrack = carTrackMapper.selectOne(carTrackQueryWrapper);
//
//            if (Objects.nonNull(carTrack) && Objects.nonNull(carTrack.getTimestamp())){
//                mileageTableVO.setStartDate(carTrack.getTimestamp());
//            } else {
//                mileageTableVO.setStartDate(mileageReportCharsTO.getStartTime());
//            }
//
//            QueryWrapper<CarTrack> carTrackQueryWrapper2 = new QueryWrapper<CarTrack>();
//            carTrackQueryWrapper2.lambda().eq(CarTrack::getCarId, stateOilDevices.get(0).getCarId());
//            carTrackQueryWrapper2.lambda().gt(CarTrack::getSpeed, 0);
//            carTrackQueryWrapper2.lambda().orderByDesc(CarTrack::getTimestamp);
//            carTrackQueryWrapper2.lambda().between(CarTrack::getTimestamp, mileageReportCharsTO.getStartTime(), mileageReportCharsTO.getEndTime());
//            carTrackQueryWrapper2.lambda().last(" LIMIT 1");
//            CarTrack carTrack2 = carTrackMapper.selectOne(carTrackQueryWrapper2);
//
//            if (Objects.nonNull(carTrack2) && Objects.nonNull(carTrack2.getTimestamp())){
//                mileageTableVO.setEndDate(carTrack2.getTimestamp());
//            } else {
//                mileageTableVO.setEndDate(mileageReportCharsTO.getEndTime());
//            }
            if (!isNotNullStateOilDevices.isEmpty()) {
                mileageTableVO.setStartDate(isNotNullStateOilDevices.get(0).getStartDate());
                mileageTableVO.setEndDate(isNotNullStateOilDevices.get(isNotNullStateOilDevices.size() - 1).getEndDate());

                mileageTableVO.setStartPosition(isNotNullStateOilDevices.get(0).getStartPosition());
                mileageTableVO.setEndPosition(isNotNullStateOilDevices.get(isNotNullStateOilDevices.size() - 1).getEndPosition());
            }
            finalMileageTableVOList.add(mileageTableVO);
        });
        mileageTableVOList = mileageTableVOList.stream().filter(x -> x.getMaxSpend().compareTo(BigDecimal.ZERO) > 0 &&
                !x.getRunTimeLength().equals("0秒")).sorted(Comparator.comparing(MileageTableVO::getDateString).reversed()).collect(Collectors.toList());
        return mileageTableVOList;
        //return Tools.buildTableDataInfo(mileageReportCharsTO.getPage(), mileageReportCharsTO.getSize(), mileageTableVOList);
    }
}
